﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;

namespace Jenvin.Library.DataStruct
{
    /// <summary>
    /// Key Level 锁  默认情况下允许一千个一同的Key。同时获得锁
    /// </summary>
    public sealed class LockManager
    {
        //private static BlockingQueue<object> m_queue = null;
        private static Queue<object> m_queue = null;
        private static readonly int LOCK_SIZE = 1000;
        private static System.Collections.Generic.Dictionary<string, object> m_dic = null;
        private static object lockerObj = new object();
        static LockManager()
        {
            m_queue = new Queue<Object>(LOCK_SIZE);
            for (int i = 0; i < LOCK_SIZE; i++)
            {
                m_queue.Enqueue(new object());
            }
            m_dic = new System.Collections.Generic.Dictionary<string, object>(LOCK_SIZE);
        }
        public static void GetLock(string key, Action doWork)
        {
            object locker = null;

            lock (lockerObj)
            {
                while (m_dic.ContainsKey(key) || m_queue.Count == 0)
                {
                    Monitor.Wait(lockerObj);
                }
                locker = m_queue.Dequeue();
                m_dic.Add(key, locker);//成功取得锁对象
                //Monitor.PulseAll(lockerObj);
            }
            try
            {
                Monitor.Enter(locker);
                doWork();
            }
            finally
            {
                lock (lockerObj)
                {
                    if (m_dic.ContainsKey(key))
                        m_dic.Remove(key);
                    m_queue.Enqueue(locker);
                    Monitor.PulseAll(lockerObj);
                }
                Monitor.Exit(locker);

            }
        }
    }
}
